home *** CD-ROM | disk | FTP | other *** search
/ Aminet 7 / Aminet 7 - August 1995.iso / Aminet / dev / c / MemPools1_2.lha / mempools / Pools.c < prev    next >
C/C++ Source or Header  |  1995-05-10  |  5KB  |  251 lines

  1. /**
  2. ***  Pool functions from amiga.lib
  3. ***
  4. ***  Version: $VER: Pools.c 1.0 (11.97.94) © D. Göhler
  5. ***
  6. ***  Adapted to match the definitions of LibAllocPooled() and
  7. ***  LibFreePooled() by Jochen Wiedmann.
  8. ***
  9. ***  This source was *NEVER* tested and just typed in from the
  10. ***  Amiga magazine, 10/94. Handle it with care.
  11. ***
  12. **/
  13.  
  14. #include <exec/types.h>
  15. #include <exec/memory.h>
  16. #include <exec/lists.h>
  17. #include <exec/execbase.h>
  18. #include <proto/exec.h>
  19. #include <clib/alib_protos.h>
  20. #include <clib/macros.h>
  21.  
  22.  
  23.  
  24.  
  25.  
  26. /**
  27. ***  The structure used for a pool.
  28. **/
  29. struct Pool
  30.   {
  31.     struct List MHAnchor;   /*  Puddle list                         */
  32.     ULONG Flags;            /*  AllocMem argument                   */
  33.     ULONG PuddleSize;       /*  Usual puddle size                   */
  34.     ULONG ThreshSize;       /*  Size that requires a special puddle */
  35.   };
  36.  
  37.  
  38.  
  39.  
  40.  
  41. /**
  42. ***  AllocMemHeader() allocates a new block of RAM from the global
  43. ***  memory list.
  44. **/
  45. STATIC struct MemHeader *AllocMemHeader(ULONG Size, ULONG Flags)
  46.  
  47. {
  48.     struct MemHeader *mh = NULL;
  49.  
  50.     /**
  51.     ***  Allocate memory
  52.     **/
  53.     if ((mh = AllocMem(Size+sizeof(*mh), Flags))) {
  54.     struct MemChunk *mc;
  55.  
  56.     /**
  57.     ***  Our memory block consists of a memheader structure,
  58.     ***  followed by a memchunk structure.
  59.     ***  We start with initializing the memchunk structure.
  60.     **/
  61.     mc = (struct MemChunk *) (mh+1);
  62.     mc->mc_Next = NULL;
  63.     mc->mc_Bytes = Size;  
  64.  
  65.     /**
  66.     ***  Initialize the memheader structure.
  67.     **/
  68.     mh->mh_Node.ln_Type = NT_MEMORY;
  69.     mh->mh_Node.ln_Name = NULL;
  70.     mh->mh_Node.ln_Succ = NULL;
  71.     mh->mh_Node.ln_Pred = NULL;
  72.     mh->mh_Node.ln_Pri = 0;
  73.     mh->mh_First = mc;
  74.     mh->mh_Lower = (APTR) mc;
  75.     mh->mh_Upper = ((UBYTE *) mc) + Size;
  76.     mh->mh_Free = Size;
  77.  
  78.     }
  79.  
  80.     return(mh);
  81. }
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88. /**
  89. ***  FreeMemHeader() is the counterpart of AllocMemHeader().
  90. **/
  91. STATIC void FreeMemHeader(struct MemHeader *mh)
  92.  
  93. {
  94.     /**
  95.     ***  Be safe
  96.     **/
  97.     if (mh) {
  98.     FreeMem(mh, (UBYTE *) mh->mh_Upper - (UBYTE *) mh->mh_Lower +
  99.             sizeof(*mh));
  100.     }
  101. }
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109. /**
  110. ***  LibCreatePool() is the CreatePool() equivalent. In fact, it calls
  111. ***  CreatePool(), if the OS is V39 or higher.
  112. **/
  113. void *LibCreatePool(ULONG Flags, ULONG PuddleSize, ULONG ThreshSize)
  114.  
  115. {
  116.     struct Pool *pool;
  117.  
  118.     if (SysBase->LibNode.lib_Version >= 39) {
  119.     return(CreatePool(Flags, PuddleSize, ThreshSize));
  120.     }
  121.  
  122.     pool = NULL;
  123.     if (ThreshSize <= PuddleSize) {
  124.     if ((pool = AllocMem(sizeof(struct Pool), MEMF_ANY))) {
  125.         pool->Flags = Flags;
  126.         pool->PuddleSize = PuddleSize;
  127.         pool->ThreshSize = ThreshSize;
  128.         NewList(&pool->MHAnchor);
  129.         pool->MHAnchor.lh_Type = NT_MEMORY;
  130.     }
  131.     }
  132.     return(pool);
  133. }
  134.  
  135.  
  136.  
  137.  
  138.  
  139. /**
  140. ***  LibDeletePool() is the counterpart of LibCreatePool().
  141. **/
  142. void LibDeletePool(APTR pool)
  143.  
  144. {
  145.     if (SysBase->LibNode.lib_Version >= 39) {
  146.     DeletePool(pool);
  147.     } else if (pool) {
  148.     while (!IsListEmpty(&((struct Pool *) pool)->MHAnchor)) {
  149.         struct MemHeader *mh;
  150.  
  151.         mh = (struct MemHeader *) ((struct Pool *) pool)->MHAnchor.lh_Head;
  152.         Remove(mh);
  153.         FreeMemHeader(mh);
  154.     }
  155.     FreeMem(pool, sizeof(struct Pool));
  156.     }
  157. }
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164. /**
  165. ***  LibAllocPooled() is the AllocPooled() equivalent. In fact, it
  166. ***  calls AllocPooled(), if the OS is V39 or higher.
  167. **/
  168. STATIC BOOL AllocPuddle(struct Pool *pool, ULONG Size)
  169.  
  170. {
  171.     struct MemHeader *mh = NULL;
  172.     int poolsize;
  173.  
  174.     poolsize = MAX(pool->PuddleSize, Size+8);
  175.     if (!(mh = AllocMemHeader(poolsize, pool->Flags))) {
  176.     return(FALSE);  /*  Failure     */
  177.     }
  178.     AddHead(&pool->MHAnchor, (struct Node *) mh);
  179.     return(TRUE);
  180. }
  181.  
  182. APTR LibAllocPooled(APTR pool, ULONG Size)
  183.  
  184. {
  185.     struct MemHeader *mh;
  186.     APTR newmem = NULL;
  187.  
  188.     if (SysBase->LibNode.lib_Version >= 39) {
  189.     return(AllocPooled(pool, Size));
  190.     }
  191.  
  192.     /**
  193.     ***  Allocate a new puddle, if puddle list is empty or Size
  194.     ***  is big.
  195.     **/
  196.     if (IsListEmpty(&((struct Pool *) pool)->MHAnchor)  ||
  197.     Size >= ((struct Pool *) pool)->ThreshSize) {
  198.     if (!AllocPuddle(pool, Size)) {
  199.         return(NULL);
  200.     }
  201.     }
  202.  
  203.     /**
  204.     ***  Look for a puddle with sufficient memory.
  205.     **/
  206.     mh = (struct MemHeader *) ((struct Pool *) pool)->MHAnchor.lh_Head;
  207.     while (mh->mh_Node.ln_Succ) {
  208.     if ((newmem = Allocate(mh, Size))) {
  209.         return(newmem);
  210.     }
  211.     mh = (struct MemHeader *) mh->mh_Node.ln_Succ;
  212.     }
  213.  
  214.     /**
  215.     ***  No puddle found, allocate a new one.
  216.     **/
  217.     if (!AllocPuddle(pool, Size)) {
  218.     return(NULL);
  219.     }
  220.     mh = (struct MemHeader *) ((struct Pool *) pool)->MHAnchor.lh_Head;
  221.     return(Allocate(mh, Size));
  222. }
  223.  
  224.  
  225.  
  226.  
  227. /**
  228. ***  LibFreePooled() is the counterpart to LibAllocPooled().
  229. **/
  230. void LibFreePooled(APTR pool, APTR mem, ULONG size)
  231.  
  232. {
  233.     struct MemHeader *mh;
  234.  
  235.     if (!mem) {
  236.     return;
  237.     }
  238.  
  239.     mh = (struct MemHeader *) ((struct Pool *) pool)->MHAnchor.lh_Head;
  240.     /**
  241.     ***  Look for the right puddle.
  242.     **/
  243.     while (mh->mh_Node.ln_Succ) {
  244.     if (mem >= mh->mh_Lower  &&  mem < mh->mh_Upper) {
  245.         Deallocate(mh, mem, size);
  246.         return;
  247.     }
  248.     mh = (struct MemHeader *) mh->mh_Node.ln_Succ;
  249.     }
  250. }
  251.